package cn.ug.analyse.service.impl;

import cn.ug.analyse.bean.request.OperationParamBean;
import cn.ug.analyse.bean.response.BaseCountExtendBean;
import cn.ug.analyse.bean.response.BaseOperationBean;
import cn.ug.analyse.bean.response.BuyGoldBean;
import cn.ug.analyse.mapper.MemberOperationMapper;
import cn.ug.analyse.service.MemberOperationService;
import cn.ug.bean.base.DataOtherTable;
import cn.ug.core.ensure.Ensure;
import cn.ug.util.Common;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author zhangweijie
 * @Date 2019/6/13 0013
 * @time 下午 13:42
 **/
@Service
public class MemberOperationServiceImpl implements MemberOperationService {

    @Autowired
    private MemberOperationMapper memberOperationMapper;

    @Override
    public DataOtherTable findOperationTotalList(OperationParamBean operationParamBean) {
        List<BaseOperationBean> resultList = new ArrayList<>();
        Boolean flag = true;
        if (StringUtils.isBlank(operationParamBean.getStartTime())) {
            flag = false;
            operationParamBean.setStartTime(LocalDate.now().plusDays(-365).toString());
        }

        if (StringUtils.isBlank(operationParamBean.getEndTime()))
            operationParamBean.setEndTime(LocalDate.now().toString());

        //参数必须传递--起始时间、结束时间
        Ensure.that(operationParamBean.getStartTime()).isNull("21000001");
        Ensure.that(operationParamBean.getEndTime()).isNull("21000002");
        //查询每天买金的人数
        List<BaseCountExtendBean> baseCountBeanList = memberOperationMapper.queryEverydayList(null);
        //每日首投人数  1.按照时间进行分组
        Map<String, List<BaseCountExtendBean>> everydayMap = baseCountBeanList.stream().collect(Collectors.groupingBy(b -> b.getDay()));
        List<BuyGoldBean> buyGoldList = new ArrayList();
        for (String key : everydayMap.keySet()) {
            BuyGoldBean buyGoldBean = new BuyGoldBean();
            buyGoldBean.setDay(key);
            List<BaseCountExtendBean> beanList = everydayMap.get(key);
            //当天首次买金
            Long firstNum = beanList.stream().filter(o -> o.getTraderNum() == 1).count();
            int agianNum = beanList.size() - firstNum.intValue();
            //当天买金总金额/交易总量
            BigDecimal buyGoldAmount = beanList.stream().map(BaseCountExtendBean::getAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            Integer buyGoldGram = beanList.stream().collect(Collectors.summingInt(BaseCountExtendBean::getTotalGram));
            buyGoldBean.setFirstBuyNum(firstNum.intValue());
            buyGoldBean.setAgainBuyNum(agianNum);
            buyGoldBean.setBuyGoldAmount(buyGoldAmount);
            //买金人数  当天所有买金用户人数，如一个用户在一天内购买了两次则仅记录为1
            buyGoldBean.setBuyGoldNum(beanList.size());
            //买金克重
            buyGoldBean.setBuyGoldGram(buyGoldGram);
            //人均购买金额=当天交易总数/当天交易总数
            //当天交易总数
            //Integer dayTraderNum = beanList.stream().collect(Collectors.summingInt(BaseCountExtendBean::getTraderNum));
            buyGoldBean.setAverageBuyGoldAmount(buyGoldAmount.divide(new BigDecimal(buyGoldBean.getBuyGoldNum()), 2, BigDecimal.ROUND_HALF_UP));
            buyGoldList.add(buyGoldBean);
        }

        int pageNum = operationParamBean.getPageNum();
        int pageSize = operationParamBean.getPageSize();
        switch (1) {
            case 1:
                resultList = findEverydayList(operationParamBean, buyGoldList);
                break; //每日
            case 2:
                //resultList = findEvenyWeek(operationParamBean,buyGoldList);
                break;    //每周
            case 3:
                // resultList = findEveryMonth(operationParamBean,buyGoldList);
                break;   //每月
        }

        //数据分页
        if (resultList != null && !resultList.isEmpty()) {
            Collections.reverse(resultList);  //倒序排列
            int total = resultList.size();
            //计算
            int num = (pageNum - 1) * pageSize;
            resultList = resultList.stream().skip(num).collect(Collectors.toList());
            List<BaseOperationBean> pageList = resultList.stream().limit(pageSize).collect(Collectors.toList());
            Map resultMap = new HashMap();

            if (!flag){
                List<Map> mapList = memberOperationMapper.queryStockList(new HashMap());
                Integer totalBuyGoldGram = resultList.stream().collect(Collectors.summingInt(BaseOperationBean::getBuyGoldGram));
                Integer totalBuyGoldNum = resultList.stream().collect(Collectors.summingInt(BaseOperationBean::getBuyGoldNum));
                BigDecimal totalTraderAmount = resultList.stream().map(BaseOperationBean::getBuyGoldAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //注册总数（人）
                resultMap.put("totalRegisterNum",resultList.stream().collect(Collectors.summingInt(BaseOperationBean::getRegisterNum)));
                //绑卡总数（人）
                resultMap.put("totalBdCardNum",resultList.stream().collect(Collectors.summingInt(BaseOperationBean::getBdCardNum)));
                //交易总数（人）  = 每日买金人数总和
                resultMap.put("totalBuyGoldNum",totalBuyGoldNum);
                //交易总量（g）  = 每日买金克重总和
                resultMap.put("totalBuyGoldGram",totalBuyGoldGram);
                //交易存量（g）
                resultMap.put("totalTraderGram",mapList.get(0).get("totalTraderGram"));
                //黄金总存量（g）
                resultMap.put("totalGoldGram",mapList.get(1).get("totalGoldGram"));
                //平台交易总金额（元） = 每日买金金额总和
                resultMap.put("totalTraderAmount",totalTraderAmount);
                //用户账户总余额（元）
                resultMap.put("totalBalanceAmount",resultList.stream().map(BaseOperationBean::getBalanceAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
                //人均购买金额（元）= 交易总量/交易总数
                resultMap.put("totalAverageBuyAmount",totalTraderAmount.divide(new BigDecimal(totalBuyGoldNum),2,BigDecimal.ROUND_HALF_UP));
            }else {
                Map paramsMap = new HashMap();
                paramsMap.put("startTime",operationParamBean.getStartTime());
                paramsMap.put("endTime",operationParamBean.getEndTime());
                List<Map> mapList = memberOperationMapper.queryStockList(paramsMap);
                Integer totalBuyGoldGram = pageList.stream().collect(Collectors.summingInt(BaseOperationBean::getBuyGoldGram));
                Integer totalBuyGoldNum = pageList.stream().collect(Collectors.summingInt(BaseOperationBean::getBuyGoldNum));
                BigDecimal totalTraderAmount = pageList.stream().map(BaseOperationBean::getBuyGoldAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
                //注册总数（人）
                resultMap.put("totalRegisterNum",pageList.stream().collect(Collectors.summingInt(BaseOperationBean::getRegisterNum)));
                //绑卡总数（人）
                resultMap.put("totalBdCardNum",pageList.stream().collect(Collectors.summingInt(BaseOperationBean::getBdCardNum)));
                //交易总数（人）  = 每日买金人数总和
                resultMap.put("totalBuyGoldNum",totalBuyGoldNum);
                //交易总量（g）  = 每日买金克重总和
                resultMap.put("totalBuyGoldGram",totalBuyGoldGram);
                //交易存量（g）
                resultMap.put("totalTraderGram",mapList.get(0).get("totalTraderGram"));
                //黄金总存量（g）
                resultMap.put("totalGoldGram",mapList.get(1).get("totalGoldGram"));
                //平台交易总金额（元） = 每日买金金额总和
                resultMap.put("totalTraderAmount",totalTraderAmount);
                //用户账户总余额（元）
                resultMap.put("totalBalanceAmount",pageList.stream().map(BaseOperationBean::getBalanceAmount).reduce(BigDecimal.ZERO, BigDecimal::add));
                //人均购买金额（元）= 交易总量/交易总数
                resultMap.put("totalAverageBuyAmount",totalTraderAmount.compareTo(new BigDecimal(0))==0?0:totalTraderAmount.divide(new BigDecimal(totalBuyGoldNum),2,BigDecimal.ROUND_HALF_UP));
            }
            return new DataOtherTable<>(pageNum, pageSize, total, pageList,resultMap);
        } else {
            return new DataOtherTable<>(pageNum, pageSize, 0, new ArrayList<>(),new HashMap<>());
        }
    }

    /**
     * 按天统计
     *
     * @param operationParamBean
     * @return
     */
    public List<BaseOperationBean> findEverydayList(OperationParamBean operationParamBean, List<BuyGoldBean> buyGoldList) {
        List<BaseOperationBean> resultList = new ArrayList<>();

        //参数必须传递--起始时间、结束时间
        Ensure.that(operationParamBean.getStartTime()).isNull("21000001");
        Ensure.that(operationParamBean.getEndTime()).isNull("21000002");

        List<BaseOperationBean> list = memberOperationMapper.queryOperationList();
        //按照类型进行分组 1,2,3,4,5  每种类型里面的日期是不会重复
        Map<Integer, List<BaseOperationBean>> typeMaplist = list.stream().collect(Collectors.groupingBy(BaseOperationBean::getType));
        List<BaseOperationBean> list1 = null;
        List<BaseOperationBean> list2 = null;
        List<BaseOperationBean> list3 = null;
        List<BaseOperationBean> list4 = null;
        List<BaseOperationBean> list5 = null;
        for (int i = 1; i <= 5; i++) {
            if (typeMaplist.get(i) != null) {
                    switch (i){
                        case 1:
                            list1 = typeMaplist.get(i);
                            break;
                        case 2:
                            list2 = typeMaplist.get(i);
                            break;
                        case 3:
                            list3 = typeMaplist.get(i);
                            break;

                        case 4:
                            list4 = typeMaplist.get(i);
                            break;

                        case 5:
                            list5 = typeMaplist.get(i);
                            break;
                    }
            }
        }
        //设置开始时间
        LocalDate startTime = LocalDate.parse(operationParamBean.getStartTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        LocalDate endTime = LocalDate.parse(operationParamBean.getEndTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        //获取查询出的天数
        int day = Integer.valueOf(Common.until(startTime, endTime) + "") + 1;
        for (int i = 0; i < day; i++) {
            //当前日期时间字符串
            String startTimeString = startTime.toString();
            BaseOperationBean entity = new BaseOperationBean();
            entity.setDay(startTimeString);
            if (list != null && !list.isEmpty()) {
                if (!CollectionUtils.isEmpty(list1)){
                    list1.stream().filter(o->o.getDay().contains(startTimeString)).forEach(bean -> {
                        entity.setRegisterNum(bean.getRegisterNum());
                        entity.setBdCardNum(bean.getBdCardNum());
                    });
                }

                if (!CollectionUtils.isEmpty(list2)){
                    list2.stream().filter(o->o.getDay().contains(startTimeString)).forEach(bean -> {
                        entity.setSoldGoldNum(bean.getSoldGoldNum());
                        entity.setSoldGoldGram(bean.getSoldGoldGram());
                    });
                }

                if (!CollectionUtils.isEmpty(list3)){
                    list3.stream().filter(o->o.getDay().contains(startTimeString)).forEach(bean -> {
                        entity.setBalanceAmount(bean.getBalanceAmount());
                    });
                }

                if (!CollectionUtils.isEmpty(list4)){
                    list4.stream().filter(o->o.getDay().contains(startTimeString)).forEach(bean -> {
                        entity.setWithdrawAmount(bean.getWithdrawAmount());
                    });
                }

                if (!CollectionUtils.isEmpty(list5)){
                    list5.stream().filter(o->o.getDay().contains(startTimeString)).forEach(bean -> {
                        entity.setCouponNum(bean.getCouponNum());
                    });
                }
                if (!CollectionUtils.isEmpty(buyGoldList)){
                    List<BuyGoldBean> resultBuyGoldList = buyGoldList.stream().filter(o -> o.getDay().contains(startTimeString)).collect(Collectors.toList());
                    if (resultBuyGoldList != null && !resultBuyGoldList.isEmpty()) {
                        BuyGoldBean buyGoldBean = resultBuyGoldList.get(0);
                        BeanUtils.copyProperties(buyGoldBean, entity);
                    }
                }
            }
            resultList.add(entity);
            startTime = startTime.plusDays(1);
        }
        return resultList;
    }
}
